home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / ASSEMBLE / H145.ZIP / ASXXXX_1.ZIP / ASMAIN.C < prev   
C/C++ Source or Header  |  1990-07-18  |  11KB  |  640 lines

  1. /* asmain.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989,1990
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include <string.h>
  15. #include <alloc.h>
  16. #include "asm.h"
  17.  
  18.  
  19. VOID
  20. main(argc, argv)
  21. char *argv[];
  22. {
  23.     register char *p;
  24.     register c, i;
  25.     struct area *ap;
  26.     FILE *afile();
  27.  
  28.     fprintf(stdout, "\n");
  29.     inpfil = -1;
  30.     for (i=1; i<argc; ++i) {
  31.         p = argv[i];
  32.         if (*p == '-') {
  33.             ++p;
  34.             while ((c = *p++) != 0)
  35.                 switch(c) {
  36.  
  37.                 case 'a':
  38.                 case 'A':
  39.                     ++aflag;
  40.                     break;
  41.  
  42.                 case 'g':
  43.                 case 'G':
  44.                     ++gflag;
  45.                     break;
  46.  
  47.                 case 'l':
  48.                 case 'L':
  49.                     ++lflag;
  50.                     break;
  51.  
  52.                 case 'o':
  53.                 case 'O':
  54.                     ++oflag;
  55.                     break;
  56.  
  57.                 case 's':
  58.                 case 'S':
  59.                     ++sflag;
  60.                     break;
  61.  
  62.                 case 'x':
  63.                 case 'X':
  64.                     xflag = 0;
  65.                     break;
  66.  
  67.                 case 'q':
  68.                 case 'Q':
  69.                     xflag = 1;
  70.                     break;
  71.  
  72.                 case 'd':
  73.                 case 'D':
  74.                     xflag = 2;
  75.                     break;
  76.  
  77.                 case 'f':
  78.                 case 'F':
  79.                     ++fflag;
  80.                     break;
  81.  
  82.                 default:
  83.                     usage();
  84.                 }
  85.         } else {
  86.             if (++inpfil == MAXFIL) {
  87.                 fprintf(stderr, "too many input files\n");
  88.                 exit(1);
  89.             }
  90.             sfp[inpfil] = afile(p, "", 0);
  91.             if (inpfil == 0) {
  92.                 if (lflag)
  93.                     lfp = afile(p, "LST", 1);
  94.                 if (oflag)
  95.                     ofp = afile(p, "REL", 1);
  96.                 if (sflag)
  97.                     tfp = afile(p, "SYM", 1);
  98.             }
  99.         }
  100.     }
  101.     if (inpfil < 0)
  102.         usage();
  103.     syminit();
  104.     for (pass=0; pass<3; ++pass) {
  105.         if (gflag && pass == 1)
  106.             symglob();
  107.         if (aflag && pass == 1)
  108.             allglob();
  109.         if (oflag && pass == 2)
  110.             outgsd();
  111.         flevel = 0;
  112.         tlevel = 0;
  113.         ifcnd[0] = 0;
  114.         iflvl[0] = 0;
  115.         radix = 10;
  116.         line = 0;
  117.         page = 0;
  118.         stb[0] = 0;
  119.         lop  = NLPP;
  120.         cfile = 0;
  121.         incfil = -1;
  122.         for (i = 0; i <= inpfil; i++)
  123.             rewind(sfp[i]);
  124.         ap = areap;
  125.         while (ap) {
  126.             ap->a_fuzz = 0;
  127.             ap->a_size = 0;
  128.             ap = ap->a_ap;
  129.         }
  130.         fuzz = 0;
  131.         dot.s_addr = 0;
  132.         dot.s_area = &dca;
  133.         symp = ˙
  134.         minit();
  135.         while (getline()) {
  136.             ++line;
  137.             cp = cb;
  138.             cpt = cbt;
  139.             ep = eb;
  140.             ip = ib;
  141.             if (setjmp(jump_env) == 0)
  142.                 asmbl();
  143.             if (pass == 2) {
  144.                 diag();
  145.                 list();
  146.             }
  147.         }
  148.         newdot(dot.s_area); /* Flush area info */
  149.         if (flevel || tlevel)
  150.             err('i');
  151.     }
  152.     if (oflag)
  153.         outchk(HUGE, HUGE);  /* Flush */
  154.     if (sflag) {
  155.         lstsym(tfp);
  156.     } else
  157.     if (lflag) {
  158.         lstsym(lfp);
  159.     }
  160. }
  161.  
  162. VOID
  163. asmbl()
  164. {
  165.     register struct mne *mp;
  166.     register struct sym *sp;
  167.     register struct tsym *tp;
  168.     register c;
  169.     struct area  *ap;
  170.     struct expr e1;
  171.     char id[NCPS];
  172.     char opt[NCPS];
  173.     char fn[FILSPC];
  174.     char *p;
  175.     int d, n, uaf, uf;
  176.  
  177.     laddr = dot.s_addr;
  178.     lmode = SLIST;
  179. loop:
  180.     if ((c=endline()) == 0) { return; }
  181.     if (ctype[c] & DIGIT) {
  182.         if (flevel)
  183.             return;
  184.         n = 0;
  185.         while ((d = digit(c, 10)) >= 0) {
  186.             n = 10*n + d;
  187.             c = get();
  188.         }
  189.         if (c != '$' || get() != ':')
  190.             qerr();
  191.         tp = symp->s_tsym;
  192.         if (pass == 0) {
  193.             while (tp) {
  194.                 if (n == tp->t_num) {
  195.                     tp->t_flg |= S_MDF;
  196.                     break;
  197.                 }
  198.                 tp = tp->t_lnk;
  199.             }
  200.             if (tp == NULL) {
  201.                 tp=(struct tsym *) new (sizeof(struct tsym));
  202.                 tp->t_lnk = symp->s_tsym;
  203.                 tp->t_num = n;
  204.                 tp->t_flg = 0;
  205.                 tp->t_area = dot.s_area;
  206.                 tp->t_addr = dot.s_addr;
  207.                 symp->s_tsym = tp;
  208.             }
  209.         } else {
  210.             while (tp) {
  211.                 if (n == tp->t_num) {
  212.                     break;
  213.                 }
  214.                 tp = tp->t_lnk;
  215.             }
  216.             if (tp) {
  217.                 if (pass == 1) {
  218.                     fuzz = tp->t_addr - dot.s_addr;
  219.                     tp->t_area = dot.s_area;
  220.                     tp->t_addr = dot.s_addr;
  221.                 } else {
  222.                     phase(tp->t_area, tp->t_addr);
  223.                     if (tp->t_flg & S_MDF)
  224.                         err('m');
  225.                 }
  226.             } else {
  227.                 err('u');
  228.             }
  229.         }
  230.         goto loop;
  231.     }
  232.     if ((ctype[c] & LETTER) == 0)
  233.         if (flevel) {
  234.             return;
  235.         } else {
  236.             qerr();
  237.         }
  238.     getid(id, c);
  239.     c = getnb();
  240.     if (c == ':') {
  241.         if (flevel)
  242.             return;
  243.         if ((c = get()) != ':') {
  244.             unget(c);
  245.             c = 0;
  246.         }
  247.         symp = lookup(id);
  248.         if (symp == &dot)
  249.             err('.');
  250.         if (pass == 0)
  251.             if ((symp->s_type != S_NEW) &&
  252.                ((symp->s_flag & S_ASG) == 0))
  253.                 symp->s_flag |= S_MDF;
  254.         if (pass != 2) {
  255.             fuzz = symp->s_addr - dot.s_addr;
  256.             symp->s_type = S_USER;
  257.             symp->s_area = dot.s_area;
  258.             symp->s_addr = dot.s_addr;
  259.         } else {
  260.             if (symp->s_flag & S_MDF)
  261.                 err('m');
  262.             phase(symp->s_area, symp->s_addr);
  263.         }
  264.         if (c) {
  265.             symp->s_flag |= S_GBL;
  266.         }
  267.         lmode = ALIST;
  268.         goto loop;
  269.     }
  270.     if (c == '=') {
  271.         if (flevel)
  272.             return;
  273.         if ((c = get()) != '=') {
  274.             unget(c);
  275.             c = 0;
  276.         }
  277.         expr(&e1, 0);
  278.         sp = lookup(id);
  279.         if (sp == &dot) {
  280.             outall();
  281.             if (e1.e_flag || e1.e_base.e_ap != dot.s_area)
  282.                 err('.');
  283.         } else
  284.         if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
  285.             err('m');
  286.         }
  287.         sp->s_type = S_USER;
  288.         sp->s_area = e1.e_base.e_ap;
  289.         sp->s_addr = laddr = e1.e_addr;
  290.         sp->s_flag |= S_ASG;
  291.         if (c) {
  292.             sp->s_flag |= S_GBL;
  293.         }
  294.         lmode = ALIST;
  295.         goto loop;
  296.     }
  297.     unget(c);
  298.     lmode = flevel ? SLIST : CLIST;
  299.     if ((mp = mlookup(id)) == NULL) {
  300.         if (!flevel)
  301.             err('o');
  302.         return;
  303.     }
  304.     switch (mp->m_type) {
  305.  
  306.     case S_IF:
  307.         n = absexpr();
  308.         if (tlevel < MAXIF) {
  309.             ++tlevel;
  310.             ifcnd[tlevel] = n;
  311.             iflvl[tlevel] = flevel;
  312.             if (n == 0) {
  313.                 ++flevel;
  314.             }
  315.         } else {
  316.             err('i');
  317.         }
  318.         lmode = ALIST;
  319.         laddr = n;
  320.         return;
  321.  
  322.     case S_ELSE:
  323.         if (ifcnd[tlevel]) {
  324.             if (++flevel > (iflvl[tlevel]+1)) {
  325.                 err('i');
  326.             }
  327.         } else {
  328.             if (--flevel < iflvl[tlevel]) {
  329.                 err('i');
  330.             }
  331.         }
  332.         lmode = SLIST;
  333.         return;
  334.  
  335.     case S_ENDIF:
  336.         if (tlevel) {
  337.             flevel = iflvl[tlevel--];
  338.         } else {
  339.             err('i');
  340.         }
  341.         lmode = SLIST;
  342.         return;
  343.  
  344.     case S_PAGE:
  345.         lop = NLPP;
  346.         lmode = NLIST;
  347.         return;
  348.  
  349.     default:
  350.         break;
  351.     }
  352.     if (flevel)
  353.         return;
  354.     switch (mp->m_type) {
  355.  
  356.     case S_EVEN:
  357.         outall();
  358.         dot.s_addr = (dot.s_addr + 1) & ~1;
  359.         lmode = SLIST;
  360.         break;
  361.  
  362.     case S_ODD:
  363.         outall();
  364.         dot.s_addr |= 1;
  365.         lmode = SLIST;
  366.         break;
  367.  
  368.     case S_BYTE:
  369.     case S_WORD:
  370.         do {
  371.             expr(&e1, 0);
  372.             if (mp->m_type == S_BYTE) {
  373.                 outrb(&e1, R_NORM);
  374.             } else {
  375.                 outrw(&e1, R_NORM);
  376.             }
  377.         } while ((c = getnb()) == ',');
  378.         unget(c);
  379.         break;
  380.  
  381.     case S_ASCII:
  382.     case S_ASCIZ:
  383.         if ((d = getnb()) == '\0')
  384.             qerr();
  385.         while ((c = getmap(d)) >= 0)
  386.             outab(c);
  387.         if (mp->m_type == S_ASCIZ)
  388.             outab(0);
  389.         break;
  390.  
  391.     case S_BLK:
  392.         expr(&e1, 0);
  393.         outall();
  394.         dot.s_addr += e1.e_addr*mp->m_valu;
  395.         break;
  396.  
  397.     case S_TITLE:
  398.         p = tb;
  399.         if ((c = getnb()) != 0) {
  400.             do {
  401.                 if (p < &tb[NTITL-1])
  402.                     *p++ = c;
  403.             } while ((c = get()) != 0);
  404.         }
  405.         *p = 0;
  406.         unget(c);
  407.         lmode = SLIST;
  408.         break;
  409.  
  410.     case S_SBTL:
  411.         p = stb;
  412.         if ((c = getnb()) != 0) {
  413.             do {
  414.                 if (p < &stb[NSBTL-1])
  415.                     *p++ = c;
  416.             } while ((c = get()) != 0);
  417.         }
  418.         *p = 0;
  419.         unget(c);
  420.         lmode = SLIST;
  421.         break;
  422.  
  423.     case S_MODUL:
  424.         getid(id, -1);
  425.         if (pass == 0) {
  426.             if (module[0])
  427.                 err('m');
  428.             strncpy(module, id, NCPS);
  429.         }
  430.         lmode = SLIST;
  431.         break;
  432.  
  433.     case S_GLOBL:
  434.         do {
  435.             getid(id, -1);
  436.             sp = lookup(id);
  437.             sp->s_flag |= S_GBL;
  438.         } while ((c = getnb()) == ',');
  439.         unget(c);
  440.         lmode = SLIST;
  441.         break;
  442.  
  443.     case S_DAREA:
  444.         getid(id, -1);
  445.         uaf = 0;
  446.         uf  = A_CON|A_REL;
  447.         if ((c = getnb()) == '(') {
  448.             do {
  449.                 getid(opt, -1);
  450.                 mp = mlookup(opt);
  451.                 if (mp && mp->m_type == S_ATYP) {
  452.                     ++uaf;
  453.                     uf |= mp->m_valu;
  454.                 } else {
  455.                     err('u');
  456.                 }
  457.             } while ((c = getnb()) == ',');
  458.             if (c != ')')
  459.                 qerr();
  460.         } else {
  461.             unget(c);
  462.         }
  463.         if ((ap = alookup(id)) != NULL) {
  464.             if (uaf && uf != ap->a_flag)
  465.                 err('m');
  466.         } else {
  467.             ap = (struct area *) new (sizeof(struct area));
  468.             ap->a_ap = areap;
  469.             strncpy(ap->a_id, id, NCPS);
  470.             ap->a_ref = areap->a_ref + 1;
  471.             ap->a_size = 0;
  472.             ap->a_fuzz = 0;
  473.             ap->a_flag = uaf ? uf : (A_CON|A_REL);
  474.             areap = ap;
  475.         }
  476.         newdot(ap);
  477.         lmode = SLIST;
  478.         break;
  479.  
  480.     case S_ORG:
  481.         if (dot.s_area->a_flag & A_ABS) {
  482.             outall();
  483.             dot.s_addr = absexpr();
  484.         } else {
  485.             err('o');
  486.         }
  487.         lmode = SLIST;
  488.         break;
  489.  
  490.     case S_RADIX:
  491.         if (more()) {
  492.             switch (getnb()) {
  493.             case 'b':
  494.             case 'B':
  495.                 radix = 2;
  496.                 break;
  497.             case '@':
  498.             case 'o':
  499.             case 'O':
  500.             case 'q':
  501.             case 'Q':
  502.                 radix = 8;
  503.                 break;
  504.             case 'd':
  505.             case 'D':
  506.                 radix = 10;
  507.                 break;
  508.             case 'h':
  509.             case 'H':
  510.             case 'x':
  511.             case 'X':
  512.                 radix = 16;
  513.                 break;
  514.             default:
  515.                 radix = 10;
  516.                 qerr();
  517.                 break;
  518.             }
  519.         } else {
  520.         radix = 10;
  521.         }
  522.         lmode = SLIST;
  523.         break;
  524.  
  525.     case S_INCL:
  526.         d = getnb();
  527.         p = fn;
  528.         while ((c = get()) != d) {
  529.             if (p < &fn[FILSPC-1]) {
  530.                 *p++ = c;
  531.             } else {
  532.                 break;
  533.             }
  534.         }
  535.         *p = 0;
  536.         if (++incfil == MAXINC ||
  537.            (ifp[incfil] = fopen(fn, "r")) == NULL) {
  538.             --incfil;
  539.             err('i');
  540.             lmode = SLIST;
  541.         } else {
  542.             lop = NLPP;
  543.             lmode = NLIST;
  544.         }
  545.         break;
  546.  
  547.     default:
  548.         machine(mp);
  549.     }
  550.     goto loop;
  551. }
  552.  
  553. FILE *
  554. afile(fn, ft, wf)
  555. char *fn;
  556. char *ft;
  557. {
  558.     register char *p1, *p2, *p3;
  559.     register c;
  560.     FILE *fp;
  561.     char fb[FILSPC];
  562.  
  563.     p1 = fn;
  564.     p2 = fb;
  565.     p3 = ft;
  566.     while ((c = *p1++) != 0 && c != FSEPX) {
  567.         if (p2 < &fb[FILSPC-4])
  568.             *p2++ = c;
  569.     }
  570.     *p2++ = FSEPX;
  571.     if (*p3 == 0) {
  572.         if (c == FSEPX) {
  573.             p3 = p1;
  574.         } else {
  575.             p3 = dsft;
  576.         }
  577.     }
  578.     while ((c = *p3++) != 0) {
  579.         if (p2 < &fb[FILSPC-1])
  580.             *p2++ = c;
  581.     }
  582.     *p2++ = 0;
  583.     if ((fp = fopen(fb, wf?"w":"r")) == NULL) {
  584.         fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
  585.         exit(1);
  586.     }
  587.     return (fp);
  588. }
  589.  
  590. VOID
  591. newdot(nap)
  592. register struct area *nap;
  593. {
  594.     register struct area *oap;
  595.  
  596.     oap = dot.s_area;
  597.     oap->a_fuzz = fuzz;
  598.     oap->a_size = dot.s_addr;
  599.     fuzz = nap->a_fuzz;
  600.     dot.s_area = nap;
  601.     dot.s_addr = nap->a_size;
  602.     outall();
  603. }
  604.  
  605. VOID
  606. phase(ap, a)
  607. struct area *ap;
  608. addr_t a;
  609. {
  610.     if (ap != dot.s_area || a != dot.s_addr)
  611.         err('p');
  612. }
  613.  
  614. char *usetxt[] = {
  615.     "Usage: [-dqxgalosf] file1 [file2 file3 ...]",
  616.     "  d    decimal    listing",
  617.     "  q    octal    listing",
  618.     "  x    hex    listing (default)",
  619.     "  g    undefined symbols made global",
  620.     "  a    all user symbols made global",
  621.     "  l    create list   output file1[LST]",
  622.     "  o    create object output file1[REL]",
  623.     "  s    create symbol output file1[SYM]",
  624.     "  f    flag relocatable references by  `   in listing file",
  625.     " ff    flag relocatable references by mode in listing file",
  626.     "",
  627.     0
  628. };
  629.  
  630. VOID
  631. usage()
  632. {
  633.     register char    **dp;
  634.  
  635.     fprintf(stderr, "\nASxxxx Assembler %s  (%s)\n\n", VERSION, cpu);
  636.     for (dp = usetxt; *dp; dp++)
  637.         fprintf(stderr, "%s\n", *dp);
  638.     exit(1);
  639. }
  640.